package com.chen;


import java.io.*;
import java.util.*;
import java.util.logging.Level;

public class LibraryManager implements LibraryService {
    private final Map<String, Book> bookMap;

    public LibraryManager() {
        this.bookMap = init();
    }

    /**
     * 初始化图书馆中的图书数据。
     *
     * @return 图书列表
     */
    @Override
    public Map<String, Book> init() {
        Map<String, Book> initBooks = new HashMap<>();
        try (
                ObjectInputStream ois = new ObjectInputStream(new FileInputStream("library-system/src/com/chen/book.dat"))
        ) {
            while (true) {
                Book book = (Book) ois.readObject();
                initBooks.put(book.getTitle(), book);
            }
        } catch (IOException e) {
            LibraryLog.log(Level.INFO, "文件读取完毕！");
            return initBooks;
        } catch (ClassNotFoundException e) {
            LibraryLog.log(Level.WARNING, "强制转换类型出错:" + e.getMessage());
            return initBooks;
        } catch (Exception e) {
            LibraryLog.log(Level.SEVERE, "文件操作异常:" + e.getMessage());
        }
        return initBooks;
    }

    /**
     * 添加一本图书到图书馆。
     *
     * @param book 要添加的图书对象
     */
    @Override
    public void addBook(Book book) {
        bookMap.put(book.getTitle(), book);
        LibraryLog.log(Level.FINE, "添加图书成功:" + book.getTitle());
        System.out.println("添加成功!");
    }

    /**
     * 根据书名从图书馆中移除一本图书。
     *
     * @param title 要移除的图书的书名
     */
    @Override
    public void removeBookByTitle(String title) {
        if (!bookMap.containsKey(title)) {
            System.out.println("未找到该图书!");
            LibraryLog.log(Level.WARNING, "未找到该图书:" + title);
            return;
        }
        bookMap.remove(title);
        LibraryLog.log(Level.FINE, "删除图书成功:" + title);
        System.out.println("删除成功!");
    }

    /**
     * 借阅一本图书。
     *
     * @param title    要借阅的图书的书名
     * @param userName 借阅者的姓名
     */
    @Override
    public void borrowBook(String title, String userName) {
        if (!bookMap.containsKey(title)) {
            System.out.println("未找到该图书!");
            LibraryLog.log(Level.WARNING, "未找到该图书:" + title);
            return;
        }
        Book book = bookMap.get(title);
        if (!book.isBorrowed()) {
            book.setBorrowed(true);
            book.setBorrower(userName);
            book.setBorrowDate(LocalDateTimeUtil.getDate());
            book.setReturner(null);
            book.setReturnDate(null);
            System.out.println("借阅成功!");
            LibraryLog.log(Level.FINE, "借阅图书成功:" + title);
            bookMap.put(title, book);
            return;
        }
        System.out.println("图书已借出!");
        LibraryLog.log(Level.WARNING, "图书已借出:" + title);
    }

    /**
     * 归还一本图书。
     *
     * @param title    要归还的图书的书名
     * @param userName 归还者的姓名
     */
    @Override
    public void returnBook(String title, String userName) {
        if (!bookMap.containsKey(title)) {
            System.out.println("未找到该图书!");
            LibraryLog.log(Level.WARNING, "未找到该图书:" + title);
            return;
        }
        Book book = bookMap.get(title);
        if (book.isBorrowed() && book.getBorrower().equals(userName)) {
            book.setBorrowed(false);
            book.setReturnDate(LocalDateTimeUtil.getDate());
            book.setReturner(userName);
            bookMap.put(title, book);
            System.out.println("归还成功!");
            LibraryLog.log(Level.FINE, "归还图书成功:" + title);
            return;
        }
        System.out.println("图书未借出或借阅者不匹配!");
        LibraryLog.log(Level.WARNING, "图书未借出或借阅者不匹配:" + title);
    }

    /**
     * 展示当前图书馆中所有图书的信息。（包括是否被借出）
     */
    @Override
    public void displayBooks() {
        showAllBorrowedBooks(bookMap.values());
    }

    public void showAllBorrowedBooks(Collection<Book> books) {
        System.out.println("书名" + "\t" + "作者" + "\t" + "ISBN" + "\t" + "借阅状态" + "\t" + "借阅日期" + "\t" + "借阅人" + "\t" + "归还日期" + "\t" + "归还人");
        if (books.isEmpty()) {
            System.out.println("暂无数据!");
            LibraryLog.log(Level.INFO, "暂无数据");
            return;
        }
        books.forEach(book -> System.out.println(book.getTitle() + "\t" + book.getAuthor() + "\t" + book.getIsbn() + "\t" + book.isBorrowed() + "\t" + book.getBorrowDate() + "\t" + book.getBorrower() + "\t" + book.getReturnDate() + "\t" + book.getReturner()));
    }

    /**
     * 保存当前图书馆中的图书数据。
     */
    @Override
    public void saveData() {
        try (
                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("library-system/src/com/chen/book.dat"))
        ) {
            bookMap.forEach((key, book) -> {// 遍历图书列表,因为不用key,所以这样省略写
                try {
                    oos.writeObject(book);
                } catch (IOException e) {
                    LibraryLog.log(Level.SEVERE, "数据保存失败:" + e.getMessage());
                }
            });
            LibraryLog.log(Level.INFO, "数据保存成功");
        } catch (Exception e) {
            LibraryLog.log(Level.SEVERE, "数据保存失败:" + e.getMessage());
        }
    }

    @Override
    public void getAllBorrowedBookByBorrower(String borrower) {
        List<Book> list = new ArrayList<>();
        for (Book book : bookMap.values()) {
            if (book.isBorrowed() && book.getBorrower().equals(borrower)) {
                list.add(book);
            }
        }
        showAllBorrowedBooks(list);
    }

    @Override
    public void getBookByTitle(String title) {
        if (bookMap.isEmpty()) {
            System.out.println("暂无数据！");
            LibraryLog.log(Level.INFO, "暂无数据");
            return;
        }
        List<Book> books = new ArrayList<>();
        for (Book book : bookMap.values()) {
            if (book.getTitle().contains(title)) {
                books.add(book);
            }
        }
        showAllBorrowedBooks(books);
    }
}
